home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / gnuplot / contrib / campbell / gterm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-27  |  52.1 KB  |  1,748 lines

  1. /* GNUPLOT - term.c */
  2. /*
  3.  * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  4.  *
  5.  * Permission to use, copy, and distribute this software and its
  6.  * documentation for any purpose with or without fee is hereby granted, 
  7.  * provided that the above copyright notice appear in all copies and 
  8.  * that both that copyright notice and this permission notice appear 
  9.  * in supporting documentation.
  10.  *
  11.  * Permission to modify the software is granted, but not the right to
  12.  * distribute the modified code.  Modifications are to be distributed 
  13.  * as patches to released version.
  14.  *  
  15.  * This software is provided "as is" without express or implied warranty.
  16.  * 
  17.  *
  18.  * AUTHORS
  19.  * 
  20.  *   Original Software:
  21.  *     Thomas Williams,  Colin Kelley.
  22.  * 
  23.  *   Gnuplot 2.0 additions:
  24.  *       Russell Lang, Dave Kotz, John Campbell.
  25.  *
  26.  *   Gnuplot 3.0 additions:
  27.  *       Gershon Elber and many others.
  28.  * 
  29.  * Send your comments or suggestions to 
  30.  *  pixar!info-gnuplot@sun.com.
  31.  * This is a mailing list; to join it send a note to 
  32.  *  pixar!info-gnuplot-request@sun.com.  
  33.  * Send bug reports to
  34.  *  pixar!bug-gnuplot@sun.com.
  35.  */
  36.  
  37.  
  38. /*-
  39.     gnuplot Graphics Terminal library: gterm.c
  40.  
  41.     This module provides access to the gnuplot terminal device drivers
  42.     as callable routines for 'C' programmers.
  43. -*/
  44.  
  45. #include <stdio.h>
  46. #define GT_OWNER
  47. #include "gtplot.h"
  48. #include "setshow.h"
  49. #include "term.h"
  50. #include "bitmap.h"
  51.  
  52. /* Definitions needed to make gterm.c standalone and usable. */
  53. #define outfile GToutfile   /* Epson and LaTeX drivers. */
  54. #define term GTterm         
  55. #define term_tbl GTterm_tbl /* eepic, latex, and sun drivers. */
  56. #define xsize GTxsize
  57. #define ysize GTysize       /* Postscript and latex drivers. */
  58. /* 
  59.    Only the Epson driver requires this gnuplot alloc (from misc.c) 
  60.    Maybe a patch can go out to just have it do a malloc for the
  61.    bitmap?   jdc
  62. */
  63.  
  64. /* alloc:
  65.  * allocate memory 
  66.  * This is a protected version of malloc used throughout gnuplot proper.
  67.  */
  68.  
  69. char *
  70. alloc(size, message)
  71.     unsigned int size;                /* # of bytes */
  72.     char *message;            /* description of what is being allocated */
  73. {
  74.     char *p;                /* the new allocation */
  75.     extern char *malloc();
  76.  
  77.     p = malloc(size);
  78.     if (p == (char *)NULL) {
  79.       if (message != NULL) {
  80.          (void) fprintf(stderr, "out of memory for %s", message);
  81.          exit(1);
  82.          /* NOTREACHED */
  83.       }
  84.           /* else we return NULL */
  85.     }
  86.     return(p);
  87. }
  88.  
  89. /* Also a fake int_error for the gterm world. */
  90. int_error(str,flag)
  91. char *str;
  92. int flag;
  93. {
  94.    fprintf (stderr, str);
  95.    exit(1);
  96. }
  97.  
  98. /* for use by all drivers */
  99. #define sign(x) ((x) >= 0 ? 1 : -1)
  100. #define abs(x) ((x) >= 0 ? (x) : -(x))
  101. #define max(a,b) ((a) > (b) ? (a) : (b))
  102. #define min(a,b) ((a) < (b) ? (a) : (b))
  103.  
  104. BOOLEAN term_init = 0;            /* true if terminal has been initialized */
  105.  
  106. extern FILE *outfile;
  107. extern char outstr[];
  108. extern BOOLEAN term_init;
  109. extern int term;
  110. extern float xsize, ysize;
  111.  
  112. /* These need to be "owned" by someone--may as well be gterm.c. */
  113. char input_line[MAX_LINE_LEN];
  114. char term_options[80]='\0';
  115. struct lexical_unit token[MAX_TOKENS];
  116. int num_tokens = 0, c_token = 0;
  117. extern struct value *const_express();
  118.  
  119. BOOLEAN interactive = 0;
  120.  
  121. /*
  122.  * instead of <strings.h>
  123.  */
  124. extern char *strcpy();
  125. extern int strlen(), strcmp(), strncmp();
  126. #ifndef AMIGA_AC_5
  127. extern double sqrt();
  128. #endif
  129.  
  130. char *getenv();
  131.  
  132. #ifdef __TURBOC__
  133. char *turboc_init();
  134. #endif
  135. #ifdef PC
  136. void reopen_binary();
  137. #endif
  138. #ifdef vms
  139. char *vms_init();
  140. void vms_reset();
  141. void term_mode_tek();
  142. void term_mode_native();
  143. void term_pasthru();
  144. void term_nopasthru();
  145. void reopen_binary();
  146. void fflush_binary();
  147. #endif
  148.  
  149. /* This is needed because the unixplot library only writes to stdout. */
  150. #ifdef UNIXPLOT
  151. FILE save_stdout;
  152. #endif
  153. int unixplot=0;
  154.  
  155. #define NICE_LINE        0
  156. #define POINT_TYPES        6
  157.  
  158.  
  159. static do_point(x,y,number)
  160. int x,y;
  161. int number;
  162. {
  163. register int htic,vtic;
  164. register struct termentry *t = &term_tbl[term];
  165.  
  166.      if (number < 0) {        /* do dot */
  167.         (*t->move)(x,y);
  168.         (*t->vector)(x,y);
  169.         return;
  170.     }
  171.  
  172.     number %= POINT_TYPES;
  173.     htic = (t->h_tic/2);    /* should be in term_tbl[] in later version */
  174.     vtic = (t->v_tic/2);    
  175.  
  176.     switch(number) {
  177.         case 0: /* do diamond */ 
  178.                 (*t->move)(x-htic,y);
  179.                 (*t->vector)(x,y-vtic);
  180.                 (*t->vector)(x+htic,y);
  181.                 (*t->vector)(x,y+vtic);
  182.                 (*t->vector)(x-htic,y);
  183.                 (*t->move)(x,y);
  184.                 (*t->vector)(x,y);
  185.                 break;
  186.         case 1: /* do plus */ 
  187.                 (*t->move)(x-htic,y);
  188.                 (*t->vector)(x-htic,y);
  189.                 (*t->vector)(x+htic,y);
  190.                 (*t->move)(x,y-vtic);
  191.                 (*t->vector)(x,y-vtic);
  192.                 (*t->vector)(x,y+vtic);
  193.                 break;
  194.         case 2: /* do box */ 
  195.                 (*t->move)(x-htic,y-vtic);
  196.                 (*t->vector)(x-htic,y-vtic);
  197.                 (*t->vector)(x+htic,y-vtic);
  198.                 (*t->vector)(x+htic,y+vtic);
  199.                 (*t->vector)(x-htic,y+vtic);
  200.                 (*t->vector)(x-htic,y-vtic);
  201.                 (*t->move)(x,y);
  202.                 (*t->vector)(x,y);
  203.                 break;
  204.         case 3: /* do X */ 
  205.                 (*t->move)(x-htic,y-vtic);
  206.                 (*t->vector)(x-htic,y-vtic);
  207.                 (*t->vector)(x+htic,y+vtic);
  208.                 (*t->move)(x-htic,y+vtic);
  209.                 (*t->vector)(x-htic,y+vtic);
  210.                 (*t->vector)(x+htic,y-vtic);
  211.                 break;
  212.         case 4: /* do triangle */ 
  213.                 (*t->move)(x,y+(4*vtic/3));
  214.                 (*t->vector)(x-(4*htic/3),y-(2*vtic/3));
  215.                 (*t->vector)(x+(4*htic/3),y-(2*vtic/3));
  216.                 (*t->vector)(x,y+(4*vtic/3));
  217.                 (*t->move)(x,y);
  218.                 (*t->vector)(x,y);
  219.                 break;
  220.         case 5: /* do star */ 
  221.                 (*t->move)(x-htic,y);
  222.                 (*t->vector)(x-htic,y);
  223.                 (*t->vector)(x+htic,y);
  224.                 (*t->move)(x,y-vtic);
  225.                 (*t->vector)(x,y-vtic);
  226.                 (*t->vector)(x,y+vtic);
  227.                 (*t->move)(x-htic,y-vtic);
  228.                 (*t->vector)(x-htic,y-vtic);
  229.                 (*t->vector)(x+htic,y+vtic);
  230.                 (*t->move)(x-htic,y+vtic);
  231.                 (*t->vector)(x-htic,y+vtic);
  232.                 (*t->vector)(x+htic,y-vtic);
  233.                 break;
  234.     }
  235. }
  236.  
  237.  
  238. /*
  239.  * general point routine
  240.  */
  241. static line_and_point(x,y,number)
  242. int x,y,number;
  243. {
  244.     /* temporary(?) kludge to allow terminals with bad linetypes 
  245.         to make nice marks */
  246.  
  247.     (*term_tbl[term].linetype)(NICE_LINE);
  248.     do_point(x,y,number);
  249. }
  250.  
  251. /* 
  252.  * general arrow routine
  253.  */
  254. #define ROOT2 (1.41421)        /* sqrt of 2 */
  255.  
  256. static do_arrow(sx, sy, ex, ey, head)
  257.     int sx,sy;            /* start point */
  258.     int ex, ey;            /* end point (point of arrowhead) */
  259.     BOOLEAN head;
  260. {
  261.     register struct termentry *t = &term_tbl[term];
  262.     int len = (t->h_tic + t->v_tic)/2; /* arrowhead size = avg of tic sizes */
  263.  
  264.     /* draw the line for the arrow. That's easy. */
  265.     (*t->move)(sx, sy);
  266.     (*t->vector)(ex, ey);
  267.  
  268.     if (head) {
  269.     /* now draw the arrow head. */
  270.     /* we put the arrowhead marks at 45 degrees to line */
  271.        if (sx == ex) {
  272.        /* vertical line, special case */
  273.           int delta = ((float)len / ROOT2 + 0.5);
  274.           if (sy < ey)
  275.               delta = -delta;    /* up arrow goes the other way */
  276.           (*t->move)(ex - delta, ey + delta);
  277.           (*t->vector)(ex,ey);
  278.           (*t->vector)(ex + delta, ey + delta);
  279.        } else {
  280.           int dx = sx - ex;
  281.           int dy = sy - ey;
  282.           double coeff = len / sqrt(2.0*((double)dx*(double)dx 
  283.                    + (double)dy*(double)dy));
  284.           int x,y;            /* one endpoint */
  285.  
  286.           x = (int)( ex + (dx + dy) * coeff );
  287.           y = (int)( ey + (dy - dx) * coeff );
  288.           (*t->move)(x,y);
  289.           (*t->vector)(ex,ey);
  290.  
  291.           x = (int)( ex + (dx - dy) * coeff );
  292.           y = (int)( ey + (dy + dx) * coeff );
  293.           (*t->vector)(x,y);
  294.        }
  295.     }
  296. }
  297.  
  298. #ifdef DUMB                    /* paper or glass dumb terminal */
  299. #include "term/dumb.trm"
  300. #endif
  301.  
  302.  
  303. #ifdef PC            /* all PC types */
  304. #include "term/pc.trm"
  305. #endif
  306.  
  307. /*
  308.    all TEK types (TEK,BITGRAPH,KERMIT,VTTEK,SELANAR) are ifdef'd in tek.trm,
  309.    but most require various TEK routines.  Hence TEK must be defined for
  310.    the others to compile.
  311. */
  312. #ifdef BITGRAPH
  313. # ifndef TEK
  314. #  define TEK
  315. # endif
  316. #endif
  317.  
  318. #ifdef SELENAR
  319. # ifndef TEK
  320. #  define TEK
  321. # endif
  322. #endif
  323.  
  324. #ifdef KERMIT
  325. # ifndef TEK
  326. #  define TEK
  327. # endif
  328. #endif
  329.  
  330. #ifdef LN03P
  331. # ifndef TEK
  332. #  define TEK
  333. # endif
  334. #endif
  335.  
  336. #ifdef VTTEK
  337. # ifndef TEK
  338. #  define TEK
  339. # endif
  340. #endif
  341.  
  342. #ifdef T410X        /* Tektronix 4106, 4107, 4109 and 420x terminals */
  343. #include "term/t410x.trm"
  344. #endif
  345.  
  346. #ifdef TEK            /* all TEK types, TEK, BBN, SELANAR, KERMIT, VTTEK */
  347. #include "term/tek.trm"
  348. #endif
  349.  
  350. #ifdef EPSONP    /* bit map types, EPSON, NEC, PROPRINTER, STAR Color */
  351. #include "term/epson.trm"
  352. #endif
  353.  
  354. #ifdef HPLJII        /* HP LaserJet II */
  355. #include "term/hpljii.trm"
  356. #endif
  357.  
  358. #ifdef HPLJII /* HP LaserJet III in HPGL mode */
  359. #  ifndef HPGL
  360. #    define HPGL
  361. #  endif
  362. #endif
  363.  
  364. #ifdef FIG                /* Fig 1.4FS Interactive graphics program */
  365. #include "term/fig.trm"
  366. #include "term/bigfig.trm"
  367. #endif
  368.   
  369. #ifdef GPR              /* Apollo Graphics Primitive Resource (fixed-size window) */
  370. #include "term/gpr.trm"
  371. #endif /* GPR */
  372.  
  373. #ifdef APOLLO           /* Apollo Graphics Primitive Resource (resizable window) */
  374. #include "term/apollo.trm"
  375. #endif /* APOLLO */
  376.  
  377. #ifdef IMAGEN        /* IMAGEN printer */
  378. #include "term/imagen.trm"
  379. #endif
  380.  
  381. #ifdef EEPIC        /* EEPIC (LATEX) type */
  382. #include "term/eepic.trm"
  383. # ifndef LATEX
  384. #  define LATEX
  385. # endif
  386. #endif
  387.  
  388. #ifdef EMTEX        /* EMTEX (LATEX for PC) type */
  389. # ifndef LATEX
  390. #  define LATEX
  391. # endif
  392. #endif
  393.  
  394. #ifdef LATEX        /* LATEX type */
  395. #include "term/latex.trm"
  396. #endif
  397.  
  398. #ifdef POSTSCRIPT    /* POSTSCRIPT type */
  399. #include "term/post.trm"
  400. #endif
  401.  
  402. #ifdef PRESCRIBE    /* PRESCRIBE type */
  403. #include "term/kyo.trm"
  404. #endif
  405.  
  406. #ifdef UNIXPC     /* unix-PC  ATT 7300 or 3b1 machine */
  407. #include "term/unixpc.trm"
  408. #endif /* UNIXPC */
  409.  
  410. #ifdef AED
  411. #include "term/aed.trm"
  412. #endif /* AED */
  413.  
  414. #ifdef CGI
  415. #include "term/cgi.trm"
  416. #endif /* CGI */
  417.  
  418. #ifdef HP2648
  419. /* also works for HP2647 */
  420. #include "term/hp2648.trm"
  421. #endif /* HP2648 */
  422.  
  423. #ifdef HP26
  424. #include "term/hp26.trm"
  425. #endif /* HP26 */
  426.  
  427. #ifdef HP75
  428. #ifndef HPGL
  429. #define HPGL
  430. #endif
  431. #endif
  432.  
  433. /* HPGL - includes HP75 and HPLJIII in HPGL mode */
  434. #ifdef HPGL
  435. #include "term/hpgl.trm"
  436. #endif /* HPGL */
  437.  
  438. /* Roland DXY800A plotter driver by Martin Yii, eln557h@monu3.OZ 
  439.     and Russell Lang, rjl@monu1.cc.monash.oz */
  440. #ifdef DXY800A
  441. #include "term/dxy.trm"
  442. #endif /* DXY800A */
  443.  
  444. #ifdef IRIS4D
  445. #include "term/iris4d.trm"
  446. #endif /* IRIS4D */
  447.  
  448. #ifdef QMS
  449. #include "term/qms.trm"
  450. #endif /* QMS */
  451.  
  452. #ifdef REGIS
  453. #include "term/regis.trm"
  454. #endif /* REGIS */
  455.  
  456. #ifdef SUN
  457. #include "term/sun.trm"
  458. #endif /* SUN */
  459.  
  460. #ifdef VWS
  461. #include "term/vws.trm"
  462. #endif /* VWS */
  463.  
  464. #ifdef V384
  465. #include "term/v384.trm"
  466. #endif /* V384 */
  467.  
  468. #ifdef UNIXPLOT
  469. #include "term/unixplot.trm"
  470. #endif /* UNIXPLOT */
  471.  
  472. #ifdef X11
  473. #include "term/x11.trm"
  474. #endif /* X11 */
  475.  
  476. #ifdef DXF
  477. #include "term/dxf.trm"
  478. #endif /* DXF */
  479.   
  480. #ifdef AMIGASCREEN
  481. #include "term/amiga.trm"
  482. #endif
  483.  
  484.  
  485. /* Dummy functions for unavailable features */
  486.  
  487. /* change angle of text.  0 is horizontal left to right.
  488. * 1 is vertical bottom to top (90 deg rotate)  
  489. */
  490. static int null_text_angle()
  491. {
  492. return FALSE ;    /* can't be done */
  493. }
  494.  
  495. /* change justification of text.  
  496.  * modes are LEFT (flush left), CENTRE (centred), RIGHT (flush right)
  497.  */
  498. static int null_justify_text()
  499. {
  500. return FALSE ;    /* can't be done */
  501. }
  502.  
  503.  
  504. /* Change scale of plot.
  505.  * Parameters are x,y scaling factors for this plot.
  506.  * Some terminals (eg latex) need to do scaling themselves.
  507.  */
  508. static int null_scale()
  509. {
  510. return FALSE ;    /* can't be done */
  511. }
  512.  
  513. static int do_scale()
  514. {
  515. return TRUE ;    /* can be done */
  516. }
  517.  
  518. static options_null()
  519. {
  520.     term_options[0] = '\0';    /* we have no options */
  521. }
  522.  
  523. static UNKNOWN_null()
  524. {
  525. }
  526.  
  527. /*
  528.  * term_tbl[] contains an entry for each terminal.  "unknown" must be the
  529.  *   first, since term is initialized to 0.
  530.  */
  531. struct termentry term_tbl[] = {
  532.     {"unknown", "Unknown terminal type - not a plotting device",
  533.       100, 100, 1, 1,
  534.       1, 1, options_null, UNKNOWN_null, UNKNOWN_null, 
  535.       UNKNOWN_null, null_scale, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, 
  536.       UNKNOWN_null, UNKNOWN_null, null_text_angle, 
  537.       null_justify_text, UNKNOWN_null, UNKNOWN_null}
  538.  
  539. #ifdef AMIGASCREEN
  540.     ,{"amiga", "Amiga Custom Screen",
  541.        AMIGA_XMAX, AMIGA_YMAX, AMIGA_VCHAR, AMIGA_HCHAR, 
  542.        AMIGA_VTIC, AMIGA_HTIC, options_null, AMIGA_init, AMIGA_reset, 
  543.        AMIGA_text, null_scale, AMIGA_graphics, AMIGA_move, AMIGA_vector,
  544.        AMIGA_linetype, AMIGA_put_text, null_text_angle, 
  545.        AMIGA_justify_text, do_point, do_arrow}
  546. #endif
  547.  
  548. #ifdef DUMB
  549.     ,{"dumb", "printer or glass dumb terminal",
  550.          DUMB_XMAX, DUMB_YMAX, 1, 1,
  551.          1, 1, DUMB_options, DUMB_init, DUMB_reset,
  552.          DUMB_text, null_scale, DUMB_graphics, DUMB_move, DUMB_vector,
  553.          DUMB_linetype, DUMB_put_text, null_text_angle,
  554.          null_justify_text, DUMB_point, DUMB_arrow}
  555. #endif
  556.  
  557. #ifdef PC
  558. #ifdef __TURBOC__
  559.  
  560.     ,{"egalib", "IBM PC/Clone with EGA graphics board",
  561.        EGALIB_XMAX, EGALIB_YMAX, EGALIB_VCHAR, EGALIB_HCHAR,
  562.        EGALIB_VTIC, EGALIB_HTIC, options_null, EGALIB_init, EGALIB_reset,
  563.        EGALIB_text, null_scale, EGALIB_graphics, EGALIB_move, EGALIB_vector,
  564.        EGALIB_linetype, EGALIB_put_text, EGALIB_text_angle, 
  565.        EGALIB_justify_text, do_point, do_arrow}
  566.  
  567.     ,{"vgalib", "IBM PC/Clone with VGA graphics board",
  568.        VGA_XMAX, VGA_YMAX, VGA_VCHAR, VGA_HCHAR,
  569.        VGA_VTIC, VGA_HTIC, options_null, VGA_init, VGA_reset,
  570.        VGA_text, null_scale, VGA_graphics, VGA_move, VGA_vector,
  571.        VGA_linetype, VGA_put_text, VGA_text_angle, 
  572.        VGA_justify_text, do_point, do_arrow}
  573.  
  574.     ,{"vgamono", "IBM PC/Clone with VGA Monochrome graphics board",
  575.        VGA_XMAX, VGA_YMAX, VGA_VCHAR, VGA_HCHAR,
  576.        VGA_VTIC, VGA_HTIC, options_null, VGA_init, VGA_reset,
  577.        VGA_text, null_scale, VGA_graphics, VGA_move, VGA_vector,
  578.        VGAMONO_linetype, VGA_put_text, VGA_text_angle, 
  579.        VGA_justify_text, line_and_point, do_arrow}
  580.  
  581.     ,{"svga", "IBM PC/Clone with Super VGA graphics board",
  582.        SVGA_XMAX, SVGA_YMAX, SVGA_VCHAR, SVGA_HCHAR,
  583.        SVGA_VTIC, SVGA_HTIC, options_null, SVGA_init, SVGA_reset,
  584.        SVGA_text, null_scale, SVGA_graphics, SVGA_move, SVGA_vector,
  585.        SVGA_linetype, SVGA_put_text, SVGA_text_angle, 
  586.        SVGA_justify_text, do_point, do_arrow}
  587.  
  588.     ,{"mcga", "IBM PC/Clone with MCGA graphics board",
  589.        MCGA_XMAX, MCGA_YMAX, MCGA_VCHAR, MCGA_HCHAR,
  590.        MCGA_VTIC, MCGA_HTIC, options_null, MCGA_init, MCGA_reset,
  591.        MCGA_text, null_scale, MCGA_graphics, MCGA_move, MCGA_vector,
  592.        MCGA_linetype, MCGA_put_text, MCGA_text_angle, 
  593.        MCGA_justify_text, line_and_point, do_arrow}
  594.  
  595.     ,{"cga", "IBM PC/Clone with CGA graphics board",
  596.        CGA_XMAX, CGA_YMAX, CGA_VCHAR, CGA_HCHAR,
  597.        CGA_VTIC, CGA_HTIC, options_null, CGA_init, CGA_reset,
  598.        CGA_text, null_scale, CGA_graphics, CGA_move, CGA_vector,
  599.        CGA_linetype, CGA_put_text, MCGA_text_angle, 
  600.        CGA_justify_text, line_and_point, do_arrow}
  601.  
  602.     ,{"hercules", "IBM PC/Clone with Hercules graphics board",
  603.        HERC_XMAX, HERC_YMAX, HERC_VCHAR, HERC_HCHAR,
  604.        HERC_VTIC, HERC_HTIC, options_null, HERC_init, HERC_reset,
  605.        HERC_text, null_scale, HERC_graphics, HERC_move, HERC_vector,
  606.        HERC_linetype, HERC_put_text, MCGA_text_angle, 
  607.        HERC_justify_text, line_and_point, do_arrow}
  608. #ifdef ATT6300
  609.     ,{"att", "IBM PC/Clone with AT&T 6300 graphics board",
  610.        ATT_XMAX, ATT_YMAX, ATT_VCHAR, ATT_HCHAR,
  611.        ATT_VTIC, ATT_HTIC, options_null, ATT_init, ATT_reset,
  612.        ATT_text, null_scale, ATT_graphics, ATT_move, ATT_vector,
  613.        ATT_linetype, ATT_put_text, ATT_text_angle, 
  614.        ATT_justify_text, line_and_point, do_arrow}
  615. #endif
  616. #else                    /* TURBO */
  617.  
  618.     ,{"cga", "IBM PC/Clone with CGA graphics board",
  619.        CGA_XMAX, CGA_YMAX, CGA_VCHAR, CGA_HCHAR,
  620.        CGA_VTIC, CGA_HTIC, options_null, CGA_init, CGA_reset,
  621.        CGA_text, null_scale, CGA_graphics, CGA_move, CGA_vector,
  622.        CGA_linetype, CGA_put_text, CGA_text_angle, 
  623.        null_justify_text, line_and_point, do_arrow}
  624.  
  625.     ,{"egabios", "IBM PC/Clone with EGA graphics board (BIOS)",
  626.        EGA_XMAX, EGA_YMAX, EGA_VCHAR, EGA_HCHAR,
  627.        EGA_VTIC, EGA_HTIC, options_null, EGA_init, EGA_reset,
  628.        EGA_text, null_scale, EGA_graphics, EGA_move, EGA_vector,
  629.        EGA_linetype, EGA_put_text, EGA_text_angle, 
  630.        null_justify_text, do_point, do_arrow}
  631.  
  632.     ,{"vgabios", "IBM PC/Clone with VGA graphics board (BIOS)",
  633.        VGA_XMAX, VGA_YMAX, VGA_VCHAR, VGA_HCHAR,
  634.        VGA_VTIC, VGA_HTIC, options_null, VGA_init, VGA_reset,
  635.        VGA_text, null_scale, VGA_graphics, VGA_move, VGA_vector,
  636.        VGA_linetype, VGA_put_text, VGA_text_angle, 
  637.        null_justify_text, do_point, do_arrow}
  638.  
  639. #ifdef EGALIB
  640.     ,{"egalib", "IBM PC/Clone with EGA graphics board (LIB)",
  641.        EGALIB_XMAX, EGALIB_YMAX, EGALIB_VCHAR, EGALIB_HCHAR,
  642.        EGALIB_VTIC, EGALIB_HTIC, options_null, EGALIB_init, EGALIB_reset,
  643.        EGALIB_text, null_scale, EGALIB_graphics, EGALIB_move, EGALIB_vector,
  644.        EGALIB_linetype, EGALIB_put_text, null_text_angle, 
  645.        null_justify_text, do_point, do_arrow}
  646. #endif
  647.  
  648. #ifdef HERCULES
  649.     ,{"hercules", "IBM PC/Clone with Hercules graphics board",
  650.        HERC_XMAX, HERC_YMAX, HERC_VCHAR, HERC_HCHAR,
  651.        HERC_VTIC, HERC_HTIC, options_null, HERC_init, HERC_reset,
  652.        HERC_text, null_scale, HERC_graphics, HERC_move, HERC_vector,
  653.        HERC_linetype, HERC_put_text, HERC_text_angle, 
  654.        null_justify_text, line_and_point, do_arrow}
  655. #endif                    /* HERCULES */
  656.  
  657. #ifdef ATT6300
  658.     ,{"att", "AT&T PC/6300 graphics",
  659.        ATT_XMAX, ATT_YMAX, ATT_VCHAR, ATT_HCHAR,
  660.        ATT_VTIC, ATT_HTIC, options_null, ATT_init, ATT_reset,
  661.        ATT_text, null_scale, ATT_graphics, ATT_move, ATT_vector,
  662.        ATT_linetype, ATT_put_text, ATT_text_angle, 
  663.        null_justify_text, line_and_point, do_arrow}
  664. #endif
  665.  
  666. #ifdef CORONA
  667.     ,{"corona325", "Corona graphics ???",
  668.        COR_XMAX, COR_YMAX, COR_VCHAR, COR_HCHAR,
  669.        COR_VTIC, COR_HTIC, options_null, COR_init, COR_reset,
  670.        COR_text, null_scale, COR_graphics, COR_move, COR_vector,
  671.        COR_linetype, COR_put_text, COR_text_angle, 
  672.        null_justify_text, line_and_point, do_arrow}
  673. #endif                    /* CORONA */
  674. #endif                    /* TURBO */
  675. #endif                    /* PC */
  676.  
  677. #ifdef AED
  678.     ,{"aed512", "AED 512 Terminal",
  679.        AED5_XMAX, AED_YMAX, AED_VCHAR, AED_HCHAR,
  680.        AED_VTIC, AED_HTIC, options_null, AED_init, AED_reset, 
  681.        AED_text, null_scale, AED_graphics, AED_move, AED_vector, 
  682.        AED_linetype, AED_put_text, null_text_angle, 
  683.        null_justify_text, do_point, do_arrow}
  684.     ,{"aed767", "AED 767 Terminal",
  685.        AED_XMAX, AED_YMAX, AED_VCHAR, AED_HCHAR,
  686.        AED_VTIC, AED_HTIC, options_null, AED_init, AED_reset, 
  687.        AED_text, null_scale, AED_graphics, AED_move, AED_vector, 
  688.        AED_linetype, AED_put_text, null_text_angle, 
  689.        null_justify_text, do_point, do_arrow}
  690. #endif
  691.  
  692. #ifdef APOLLO
  693.        ,{"apollo", "Apollo Graphics Primitive Resource, rescaling of subsequent plots after window resizing",
  694.        0, 0, 0, 0, /* APOLLO_XMAX, APOLLO_YMAX, APOLLO_VCHAR, APOLLO_HCHAR, are filled in at run-time */
  695.        APOLLO_VTIC, APOLLO_HTIC, options_null, APOLLO_init, APOLLO_reset,
  696.        APOLLO_text, null_scale, APOLLO_graphics, APOLLO_move, APOLLO_vector,
  697.        APOLLO_linetype, APOLLO_put_text, APOLLO_text_angle,
  698.        APOLLO_justify_text, line_and_point, do_arrow}
  699. #endif
  700.  
  701. #ifdef GPR
  702.        ,{"gpr", "Apollo Graphics Primitive Resource, fixed-size window",
  703.        GPR_XMAX, GPR_YMAX, GPR_VCHAR, GPR_HCHAR,
  704.        GPR_VTIC, GPR_HTIC, options_null, GPR_init, GPR_reset,
  705.        GPR_text, null_scale, GPR_graphics, GPR_move, GPR_vector,
  706.        GPR_linetype, GPR_put_text, GPR_text_angle,
  707.        GPR_justify_text, line_and_point, do_arrow}
  708. #endif
  709.  
  710. #ifdef BITGRAPH
  711.     ,{"bitgraph", "BBN Bitgraph Terminal",
  712.        BG_XMAX,BG_YMAX,BG_VCHAR, BG_HCHAR, 
  713.        BG_VTIC, BG_HTIC, options_null, BG_init, BG_reset, 
  714.        BG_text, null_scale, BG_graphics, BG_move, BG_vector,
  715.        BG_linetype, BG_put_text, null_text_angle, 
  716.        null_justify_text, line_and_point, do_arrow}
  717. #endif
  718.  
  719. #ifdef CGI
  720.     ,{"cgi", "SCO CGI drivers (requires CGIDISP or CGIPRNT env variable)",
  721.        CGI_XMAX, CGI_YMAX, 0, 0, 
  722.        CGI_VTIC, 0, options_null, CGI_init, CGI_reset, 
  723.        CGI_text, null_scale, CGI_graphics, CGI_move, CGI_vector, 
  724.        CGI_linetype, CGI_put_text, CGI_text_angle, 
  725.        CGI_justify_text, CGI_point, do_arrow}
  726.  
  727.     ,{"hcgi", "SCO CGI drivers (hardcopy, requires CGIPRNT env variable)",
  728.        CGI_XMAX, CGI_YMAX, 0, 0, 
  729.        CGI_VTIC, 0, options_null, HCGI_init, CGI_reset, 
  730.        CGI_text, null_scale, CGI_graphics, CGI_move, CGI_vector, 
  731.        CGI_linetype, CGI_put_text, CGI_text_angle, 
  732.        CGI_justify_text, CGI_point, do_arrow}
  733. #endif
  734.  
  735. #ifdef DXF
  736.     ,{"dxf", "dxf-file for AutoCad (default size 120x80)",
  737.        DXF_XMAX,DXF_YMAX,DXF_VCHAR, DXF_HCHAR,
  738.        DXF_VTIC, DXF_HTIC, options_null,DXF_init, DXF_reset,
  739.        DXF_text, null_scale, DXF_graphics, DXF_move, DXF_vector,
  740.        DXF_linetype, DXF_put_text, DXF_text_angle,
  741.        DXF_justify_text, do_point, do_arrow}
  742. #endif
  743.  
  744. #ifdef DXY800A
  745.     ,{"dxy800a", "Roland DXY800A plotter",
  746.        DXY_XMAX, DXY_YMAX, DXY_VCHAR, DXY_HCHAR,
  747.        DXY_VTIC, DXY_HTIC, options_null, DXY_init, DXY_reset,
  748.        DXY_text, null_scale, DXY_graphics, DXY_move, DXY_vector,
  749.        DXY_linetype, DXY_put_text, DXY_text_angle, 
  750.        null_justify_text, do_point, do_arrow}
  751. #endif
  752.  
  753. #ifdef EEPIC
  754.     ,{"eepic", "EEPIC -- extended LaTeX picture environment",
  755.        EEPIC_XMAX, EEPIC_YMAX, EEPIC_VCHAR, EEPIC_HCHAR, 
  756.        EEPIC_VTIC, EEPIC_HTIC, options_null, EEPIC_init, EEPIC_reset, 
  757.        EEPIC_text, EEPIC_scale, EEPIC_graphics, EEPIC_move, EEPIC_vector, 
  758.        EEPIC_linetype, EEPIC_put_text, EEPIC_text_angle, 
  759.        EEPIC_justify_text, EEPIC_point, EEPIC_arrow}
  760. #endif
  761.  
  762. #ifdef EMTEX
  763.    
  764.     ,{"emtex", "LATEX picture environment with emTeX specials",
  765.        LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR, 
  766.        LATEX_VTIC, LATEX_HTIC, options_null, EMTEX_init, EMTEX_reset, 
  767.        EMTEX_text, LATEX_scale, LATEX_graphics, LATEX_move, LATEX_vector, 
  768.        LATEX_linetype, LATEX_put_text, LATEX_text_angle, 
  769.        LATEX_justify_text, LATEX_point, LATEX_arrow}
  770. #endif
  771.  
  772. #ifdef EPS60
  773.     ,{"epson_60dpi", "Epson-style 60-dot per inch printers",
  774.        EPS60XMAX, EPS60YMAX, EPSONVCHAR, EPSONHCHAR,
  775.        EPSONVTIC, EPSONHTIC, options_null, EPSONinit, EPSONreset,
  776.        EPS60text, null_scale, EPS60graphics, EPSONmove, EPSONvector,
  777.        EPSONlinetype, EPSONput_text, EPSON_text_angle,
  778.        null_justify_text, do_point, do_arrow}
  779. #endif
  780.  
  781. #ifdef EPSONP
  782.     ,{"epson_lx800", "Epson LX-800, Star NL-10, NX-1000, PROPRINTER ...",
  783.        EPSONXMAX, EPSONYMAX, EPSONVCHAR, EPSONHCHAR, 
  784.        EPSONVTIC, EPSONHTIC, options_null, EPSONinit, EPSONreset, 
  785.        EPSONtext, null_scale, EPSONgraphics, EPSONmove, EPSONvector, 
  786.        EPSONlinetype, EPSONput_text, EPSON_text_angle, 
  787.        null_justify_text, line_and_point, do_arrow}
  788. #endif
  789.  
  790. #ifdef FIG
  791.     ,{"fig", "FIG graphics language: SunView or X graphics editor",
  792.        FIG_XMAX, FIG_YMAX, FIG_VCHAR, FIG_HCHAR, 
  793.        FIG_VTIC, FIG_HTIC, options_null, FIG_init, FIG_reset, 
  794.        FIG_text, null_scale, FIG_graphics, FIG_move, FIG_vector, 
  795.        FIG_linetype, FIG_put_text, FIG_text_angle, 
  796.        FIG_justify_text, do_point, FIG_arrow}
  797.     ,{"bfig", "FIG graphics language: SunView or X graphics editor. Large Graph",
  798.        BFIG_XMAX, BFIG_YMAX, BFIG_VCHAR, BFIG_HCHAR, 
  799.        BFIG_VTIC, BFIG_HTIC, options_null, FIG_init, FIG_reset, 
  800.        FIG_text, null_scale, FIG_graphics, FIG_move, BFIG_vector, 
  801.        FIG_linetype, BFIG_put_text, FIG_text_angle, 
  802.        FIG_justify_text, do_point, BFIG_arrow}
  803. #endif
  804.  
  805. #ifdef HP26
  806.     ,{"hp2623A", "HP2623A and maybe others",
  807.        HP26_XMAX, HP26_YMAX, HP26_VCHAR, HP26_HCHAR,
  808.        HP26_VTIC, HP26_HTIC, options_null, HP26_init, HP26_reset,
  809.        HP26_text, null_scale, HP26_graphics, HP26_move, HP26_vector,
  810.        HP26_linetype, HP26_put_text, null_text_angle, 
  811.        null_justify_text, line_and_point, do_arrow}
  812. #endif
  813.  
  814. #ifdef HP2648
  815.     ,{"hp2648", "HP2648 and HP2647",
  816.        HP2648XMAX, HP2648YMAX, HP2648VCHAR, HP2648HCHAR, 
  817.        HP2648VTIC, HP2648HTIC, options_null, HP2648init, HP2648reset, 
  818.        HP2648text, null_scale, HP2648graphics, HP2648move, HP2648vector, 
  819.        HP2648linetype, HP2648put_text, HP2648_text_angle, 
  820.        null_justify_text, line_and_point, do_arrow}
  821. #endif
  822.  
  823. #ifdef HP75
  824.     ,{"hp7580B", "HP7580, and probably other HPs (4 pens)",
  825.        HPGL_XMAX, HPGL_YMAX, HPGL_VCHAR, HPGL_HCHAR,
  826.        HPGL_VTIC, HPGL_HTIC, options_null, HPGL_init, HPGL_reset,
  827.        HPGL_text, null_scale, HPGL_graphics, HPGL_move, HPGL_vector,
  828.        HP75_linetype, HPGL_put_text, HPGL_text_angle, 
  829.        null_justify_text, do_point, do_arrow}
  830. #endif
  831.  
  832. #ifdef HPGL
  833.     ,{"hpgl", "HP7475 and (hopefully) lots of others (6 pens)",
  834.        HPGL_XMAX, HPGL_YMAX, HPGL_VCHAR, HPGL_HCHAR,
  835.        HPGL_VTIC, HPGL_HTIC, options_null, HPGL_init, HPGL_reset,
  836.        HPGL_text, null_scale, HPGL_graphics, HPGL_move, HPGL_vector,
  837.        HPGL_linetype, HPGL_put_text, HPGL_text_angle, 
  838.        null_justify_text, do_point, do_arrow}
  839. #endif
  840.  
  841. #ifdef HPLJII
  842.     ,{"hpljii", "HP Laserjet series II, [75 100 150 300]",
  843.        HPLJII_75PPI_XMAX, HPLJII_75PPI_YMAX, HPLJII_75PPI_VCHAR,
  844.        HPLJII_75PPI_HCHAR, HPLJII_75PPI_VTIC, HPLJII_75PPI_HTIC, HPLJIIoptions,
  845.        HPLJIIinit, HPLJIIreset, HPLJIItext, null_scale,
  846.        HPLJIIgraphics, HPLJIImove, HPLJIIvector, HPLJIIlinetype,
  847.        HPLJIIput_text, HPLJIItext_angle, null_justify_text, line_and_point,
  848.        do_arrow}
  849.     ,{"hpdj", "HP DeskJet 500, [75 100 150 300]",
  850.        HPLJII_75PPI_XMAX, HPLJII_75PPI_YMAX, HPLJII_75PPI_VCHAR,
  851.        HPLJII_75PPI_HCHAR, HPLJII_75PPI_VTIC, HPLJII_75PPI_HTIC, HPLJIIoptions,
  852.        HPLJIIinit, HPLJIIreset, HPDJtext, null_scale,
  853.        HPDJgraphics, HPLJIImove, HPLJIIvector, HPLJIIlinetype,
  854.        HPDJput_text, HPDJtext_angle, null_justify_text, line_and_point,
  855.        do_arrow}
  856. #endif
  857.  
  858. #ifdef HPLJIII
  859.     ,{"hpljiii_port", "HP laserjet iii (using HPGL plot vectors), portrait mode",
  860.     HPGL_XMAX, HPGL_YMAX, HPGL_VCHAR, HPGL_HCHAR,
  861.     HPGL_VTIC, HPGL_HTIC, options_null, HPLJIII_PORT_init, HPLJIII_reset,
  862.     HPGL_text, null_scale, HPGL_graphics, HPGL_move, HPGL_vector,
  863.     HPGL_linetype, HPGL_put_text, HPGL_text_angle,
  864.     null_justify_text, do_point, do_arrow}
  865.      ,{"hpljiii_land", "HP laserjet iii (using HPGL plot vectors), landscape mode",
  866.     HPGL_XMAX, HPGL_YMAX, HPGL_VCHAR, HPGL_HCHAR,
  867.     HPGL_VTIC, HPGL_HTIC, options_null, HPLJIII_LAND_init, HPLJIII_reset,
  868.     HPGL_text, null_scale, HPGL_graphics, HPGL_move, HPGL_vector,
  869.     HPGL_linetype, HPGL_put_text, HPGL_text_angle,
  870.     null_justify_text, do_point, do_arrow}
  871. #endif
  872.  
  873. #ifdef IMAGEN
  874.     ,{"imagen", "Imagen laser printer",
  875.        IMAGEN_XMAX, IMAGEN_YMAX, IMAGEN_VCHAR, IMAGEN_HCHAR, 
  876.        IMAGEN_VTIC, IMAGEN_HTIC, options_null, IMAGEN_init, IMAGEN_reset, 
  877.        IMAGEN_text, null_scale, IMAGEN_graphics, IMAGEN_move, 
  878.        IMAGEN_vector, IMAGEN_linetype, IMAGEN_put_text, IMAGEN_text_angle,
  879.        IMAGEN_justify_text, line_and_point, do_arrow}
  880. #endif
  881.  
  882. #ifdef IRIS4D
  883.     ,{"iris4d", "Silicon Graphics IRIS 4D Series Computer",
  884.        IRIS4D_XMAX, IRIS4D_YMAX, IRIS4D_VCHAR, IRIS4D_HCHAR, 
  885.        IRIS4D_VTIC, IRIS4D_HTIC, IRIS4D_options, IRIS4D_init, IRIS4D_reset, 
  886.        IRIS4D_text, null_scale, IRIS4D_graphics, IRIS4D_move, IRIS4D_vector,
  887.        IRIS4D_linetype, IRIS4D_put_text, null_text_angle, 
  888.        null_justify_text, do_point, do_arrow}
  889. #endif
  890.  
  891. #ifdef KERMIT
  892.     ,{"kc_tek40xx", "Kermit-MS tek40xx terminal emulator - color",
  893.        TEK40XMAX,TEK40YMAX,TEK40VCHAR, KTEK40HCHAR, 
  894.        TEK40VTIC, TEK40HTIC, options_null, TEK40init, KTEK40reset, 
  895.        KTEK40Ctext, null_scale, KTEK40graphics, TEK40move, TEK40vector, 
  896.        KTEK40Clinetype, TEK40put_text, null_text_angle, 
  897.        null_justify_text, do_point, do_arrow}
  898.     ,{"km_tek40xx", "Kermit-MS tek40xx terminal emulator - monochrome",
  899.        TEK40XMAX,TEK40YMAX,TEK40VCHAR, KTEK40HCHAR, 
  900.        TEK40VTIC, TEK40HTIC, options_null, TEK40init, KTEK40reset, 
  901.        TEK40text, null_scale, KTEK40graphics, TEK40move, TEK40vector, 
  902.        KTEK40Mlinetype, TEK40put_text, null_text_angle, 
  903.        null_justify_text, line_and_point, do_arrow}
  904. #endif
  905.  
  906. #ifdef LATEX
  907.     ,{"latex", "LaTeX picture environment",
  908.        LATEX_XMAX, LATEX_YMAX, LATEX_VCHAR, LATEX_HCHAR, 
  909.        LATEX_VTIC, LATEX_HTIC, options_null, LATEX_init, LATEX_reset, 
  910.        LATEX_text, LATEX_scale, LATEX_graphics, LATEX_move, LATEX_vector, 
  911.        LATEX_linetype, LATEX_put_text, LATEX_text_angle, 
  912.        LATEX_justify_text, LATEX_point, LATEX_arrow}
  913. #endif
  914.  
  915. #ifdef LN03P
  916.      ,{"ln03", "LN03-plus laser printer in tektronix mode",
  917.     TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR,
  918.     TEK40VTIC, TEK40HTIC, options_null, LN03Pinit, LN03Preset,
  919.     TEK40text, null_scale, TEK40graphics, TEK40move, TEK40vector,
  920.     TEK40linetype, TEK40put_text, null_text_angle,
  921.     null_justify_text, line_and_point, do_arrow}
  922. #endif
  923.  
  924. #ifdef NEC
  925.     ,{"nec_cp6m", "NEC printer CP6, Epson LQ-800 Monochrome",
  926.        NECXMAX, NECYMAX, NECVCHAR, NECHCHAR, 
  927.        NECVTIC, NECHTIC, options_null, NECinit, NECreset, 
  928.        NECtext, null_scale, NECMgraphics, NECmove, NECvector, 
  929.        NECMlinetype, NECput_text, NEC_text_angle, 
  930.        null_justify_text, line_and_point, do_arrow}
  931.     ,{"nec_cp6c", "NEC printer CP6 Color",
  932.        NECXMAX, NECYMAX, NECVCHAR, NECHCHAR, 
  933.        NECVTIC, NECHTIC, options_null, NECinit, NECreset, 
  934.        NECtext, null_scale, NECCgraphics, NECmove, NECvector, 
  935.        NECClinetype, NECput_text, NEC_text_angle, 
  936.        null_justify_text, do_point, do_arrow}
  937.     ,{"nec_cp6d", "NEC printer CP6, Epson LQ-800 Draft monochrome",
  938.        NECXMAX, NECYMAX, NECVCHAR, NECHCHAR, 
  939.        NECVTIC, NECHTIC, options_null, NECinit, NECreset, 
  940.        NECdraft_text, null_scale, NECMgraphics, NECmove, NECvector, 
  941.        NECMlinetype, NECput_text, NEC_text_angle, 
  942.        null_justify_text, line_and_point, do_arrow}
  943. #endif
  944.  
  945. #ifdef POSTSCRIPT
  946.     ,{"postscript", "PostScript graphics language [mode \042fontname\042 font_size]",
  947.        PS_XMAX, PS_YMAX, PS_VCHAR, PS_HCHAR, 
  948.        PS_VTIC, PS_HTIC, PS_options, PS_init, PS_reset, 
  949.        PS_text, do_scale, PS_graphics, PS_move, PS_vector, 
  950.        PS_linetype, PS_put_text, PS_text_angle, 
  951.        PS_justify_text, PS_point, do_arrow}
  952. #endif
  953.  
  954. #ifdef PRESCRIBE
  955.     ,{"prescribe", "Prescribe - for the Kyocera Laser Printer",
  956.     PRE_XMAX, PRE_YMAX, PRE_VCHAR, PRE_HCHAR, 
  957.     PRE_VTIC, PRE_HTIC, options_null, PRE_init, PRE_reset, 
  958.     PRE_text, null_scale, PRE_graphics, PRE_move, PRE_vector, 
  959.     PRE_linetype, PRE_put_text, null_text_angle, 
  960.     PRE_justify_text, line_and_point, do_arrow}
  961.     ,{"kyo", "Kyocera Laser Printer with Courier font",
  962.     PRE_XMAX, PRE_YMAX, KYO_VCHAR, KYO_HCHAR, 
  963.     PRE_VTIC, PRE_HTIC, options_null, KYO_init, PRE_reset, 
  964.     PRE_text, null_scale, PRE_graphics, PRE_move, PRE_vector, 
  965.     PRE_linetype, PRE_put_text, null_text_angle, 
  966.     PRE_justify_text, line_and_point, do_arrow}
  967. #endif /* PRESCRIBE */
  968.  
  969. #ifdef QMS
  970.     ,{"qms", "QMS/QUIC Laser printer (also Talaris 1200 and others)",
  971.        QMS_XMAX,QMS_YMAX, QMS_VCHAR, QMS_HCHAR, 
  972.        QMS_VTIC, QMS_HTIC, options_null, QMS_init,QMS_reset, 
  973.        QMS_text, null_scale, QMS_graphics, QMS_move, QMS_vector,
  974.        QMS_linetype,QMS_put_text, null_text_angle, 
  975.        null_justify_text, line_and_point, do_arrow}
  976. #endif
  977.  
  978. #ifdef REGIS
  979.     ,{"regis", "REGIS graphics language",
  980.        REGISXMAX, REGISYMAX, REGISVCHAR, REGISHCHAR, 
  981.        REGISVTIC, REGISHTIC, options_null, REGISinit, REGISreset, 
  982.        REGIStext, null_scale, REGISgraphics, REGISmove, REGISvector,
  983.        REGISlinetype, REGISput_text, REGIStext_angle, 
  984.        null_justify_text, line_and_point, do_arrow}
  985. #endif
  986.  
  987.  
  988. #ifdef SELANAR
  989.     ,{"selanar", "Selanar",
  990.        TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR, 
  991.        TEK40VTIC, TEK40HTIC, options_null, SEL_init, SEL_reset, 
  992.        SEL_text, null_scale, SEL_graphics, TEK40move, TEK40vector, 
  993.        TEK40linetype, TEK40put_text, null_text_angle, 
  994.        null_justify_text, line_and_point, do_arrow}
  995. #endif
  996.  
  997. #ifdef STARC
  998.     ,{"starc", "Star Color Printer",
  999.        STARCXMAX, STARCYMAX, STARCVCHAR, STARCHCHAR, 
  1000.        STARCVTIC, STARCHTIC, options_null, STARCinit, STARCreset, 
  1001.        STARCtext, null_scale, STARCgraphics, STARCmove, STARCvector, 
  1002.        STARClinetype, STARCput_text, STARC_text_angle, 
  1003.        null_justify_text, line_and_point, do_arrow}
  1004. #endif
  1005.  
  1006. #ifdef SUN
  1007.     ,{"sun", "SunView window system",
  1008.        SUN_XMAX, SUN_YMAX, SUN_VCHAR, SUN_HCHAR, 
  1009.        SUN_VTIC, SUN_HTIC, options_null, SUN_init, SUN_reset, 
  1010.        SUN_text, null_scale, SUN_graphics, SUN_move, SUN_vector,
  1011.        SUN_linetype, SUN_put_text, null_text_angle, 
  1012.        SUN_justify_text, line_and_point, do_arrow}
  1013. #endif
  1014.  
  1015. #ifdef VWS
  1016.     ,{"VWS", "VAX Windowing System (UIS)",
  1017.            VWS_XMAX, VWS_YMAX, VWS_VCHAR, VWS_HCHAR,
  1018.            VWS_VTIC, VWS_HTIC, options_null, VWS_init, VWS_reset,
  1019.            VWS_text, null_scale, VWS_graphics, VWS_move, VWS_vector,
  1020.            VWS_linetype, VWS_put_text, VWS_text_angle,
  1021.            VWS_justify_text, do_point, do_arrow}
  1022. #endif
  1023.  
  1024. #ifdef TANDY60
  1025.     ,{"tandy_60dpi", "Tandy DMP-130 series 60-dot per inch graphics",
  1026.        EPS60XMAX, EPS60YMAX, EPSONVCHAR, EPSONHCHAR,
  1027.        EPSONVTIC, EPSONHTIC, options_null, EPSONinit, EPSONreset,
  1028.        TANDY60text, null_scale, EPS60graphics, EPSONmove, EPSONvector,
  1029.        EPSONlinetype, EPSONput_text, EPSON_text_angle,
  1030.        null_justify_text, do_point, do_arrow}
  1031. #endif
  1032.  
  1033. #ifdef T410X
  1034.     ,{"tek410x", "Tektronix 4106, 4107, 4109 and 420X terminals",
  1035.        T410XXMAX, T410XYMAX, T410XVCHAR, T410XHCHAR, 
  1036.        T410XVTIC, T410XHTIC, options_null, T410X_init, T410X_reset, 
  1037.        T410X_text, null_scale, T410X_graphics, T410X_move, T410X_vector, 
  1038.        T410X_linetype, T410X_put_text, T410X_text_angle, 
  1039.        null_justify_text, T410X_point, do_arrow}
  1040. #endif
  1041.  
  1042. #ifdef TEK
  1043.     ,{"tek40xx", "Tektronix 4010 and others; most TEK emulators",
  1044.        TEK40XMAX, TEK40YMAX, TEK40VCHAR, TEK40HCHAR, 
  1045.        TEK40VTIC, TEK40HTIC, options_null, TEK40init, TEK40reset, 
  1046.        TEK40text, null_scale, TEK40graphics, TEK40move, TEK40vector, 
  1047.        TEK40linetype, TEK40put_text, null_text_angle, 
  1048.        null_justify_text, line_and_point, do_arrow}
  1049. #endif
  1050.  
  1051. #ifdef UNIXPLOT
  1052.     ,{"unixplot", "Unix plotting standard (see plot(1))",
  1053.        UP_XMAX, UP_YMAX, UP_VCHAR, UP_HCHAR, 
  1054.        UP_VTIC, UP_HTIC, options_null, UP_init, UP_reset, 
  1055.        UP_text, null_scale, UP_graphics, UP_move, UP_vector, 
  1056.        UP_linetype, UP_put_text, null_text_angle, 
  1057.        null_justify_text, line_and_point, do_arrow}
  1058. #endif
  1059.     
  1060. #ifdef UNIXPC
  1061.     ,{"unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
  1062.        uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR, 
  1063.        uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset, 
  1064.        uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
  1065.        uPC_linetype, uPC_put_text, uPC_text_angle, 
  1066.        null_justify_text, line_and_point, do_arrow}
  1067. #endif
  1068.  
  1069. #ifdef V384
  1070.     ,{"vx384", "Vectrix 384 and Tandy color printer",
  1071.        V384_XMAX, V384_YMAX, V384_VCHAR, V384_HCHAR, 
  1072.        V384_VTIC, V384_HTIC, options_null, V384_init, V384_reset, 
  1073.        V384_text, null_scale, V384_graphics, V384_move, V384_vector, 
  1074.        V384_linetype, V384_put_text, null_text_angle, 
  1075.        null_justify_text, do_point, do_arrow}
  1076. #endif
  1077.  
  1078. #ifdef VTTEK
  1079.     ,{"vttek", "VT-like tek40xx terminal emulator",
  1080.        TEK40XMAX,TEK40YMAX,TEK40VCHAR, TEK40HCHAR,
  1081.        TEK40VTIC, TEK40HTIC, options_null, VTTEK40init, VTTEK40reset,
  1082.        TEK40text, null_scale, TEK40graphics, TEK40move, TEK40vector,
  1083.        VTTEK40linetype, VTTEK40put_text, null_text_angle,
  1084.        null_justify_text, line_and_point, do_arrow}
  1085. #endif
  1086.  
  1087. #ifdef X11
  1088.     ,{"x11", "X11 Window System",
  1089.        X11_XMAX, X11_YMAX, X11_VCHAR, X11_HCHAR, 
  1090.        X11_VTIC, X11_HTIC, options_null, X11_init, X11_reset, 
  1091.        X11_text, null_scale, X11_graphics, X11_move, X11_vector, 
  1092.        X11_linetype, X11_put_text, null_text_angle, 
  1093.        X11_justify_text, line_and_point, do_arrow}
  1094.     ,{"X11", "X11 Window System - multi-color points",
  1095.        X11_XMAX, X11_YMAX, X11_VCHAR, X11_HCHAR, 
  1096.        X11_VTIC, X11_HTIC, options_null, X11_init, X11_reset, 
  1097.        X11_text, null_scale, X11_graphics, X11_move, X11_vector, 
  1098.        X11_linetype, X11_put_text, null_text_angle, 
  1099.        X11_justify_text, do_point, do_arrow}
  1100. #endif
  1101. };
  1102.  
  1103. #define TERMCOUNT (sizeof(term_tbl)/sizeof(struct termentry))
  1104.  
  1105.  
  1106. gt_list_terms()
  1107. {
  1108. register int i;
  1109.  
  1110.     fprintf(stderr,"\nAvailable terminal types:\n");
  1111.     for (i = 0; i < TERMCOUNT; i++)
  1112.         fprintf(stderr,"  %15s  %s\n",
  1113.                term_tbl[i].name, term_tbl[i].description);
  1114.     (void) putc('\n',stderr);
  1115. }
  1116.  
  1117.  
  1118. #ifdef NOT_USED_IN_GPLOTLIB
  1119. /* set_term: get terminal number from name on command line */
  1120. /* will change 'term' variable if successful */
  1121. int                        /* term number */
  1122. set_term(c_token)
  1123. int c_token;
  1124. {
  1125.     register int t;
  1126.     char *input_name;
  1127.  
  1128.     if (!token[c_token].is_token)
  1129.      int_error("terminal name expected",c_token);
  1130.     t = -1;
  1131.     input_name = input_line + token[c_token].start_index;
  1132.     t = gt_change_term(input_name, token[c_token].length);
  1133.     if (t == -1)
  1134.      int_error("unknown terminal type; type just 'set terminal' for a list",
  1135.              c_token);
  1136.     if (t == -2)
  1137.      int_error("ambiguous terminal name; type just 'set terminal' for a list",
  1138.              c_token);
  1139.  
  1140.     /* otherwise the type was changed */
  1141.  
  1142.     return(t);
  1143. }
  1144. #endif
  1145.  
  1146. gt_change_file (fp)
  1147. FILE *fp;
  1148. /*-
  1149.    Routine to change the file pointer (stream) being used to write
  1150.    to with gplotlib (GToutfile).  This is generally preferred to just
  1151.    replacing GToutfile on the fly as it will flush any output and
  1152.    also handles unixplot files properly.  Note that GSRoutfile is
  1153.    really the same as GToutfile, so this routine serves the function
  1154.    of changing the outfile for gsr code also.
  1155.  
  1156.    Parameter:
  1157.  
  1158.           fp: New value to use for GToutfile (pointer from fopen()),
  1159.               if NULL then replace GToutfile with original stdout
  1160.               value.
  1161. -*/
  1162. {
  1163. /* 
  1164.    Most of this code is just taken from SET OUTPUT in order to handle
  1165.    the unixplot redirections.  Guess it's worth it...
  1166. */
  1167.    if (fp == NULL) {
  1168.       UP_redirect (4);
  1169.       if (outfile != stdout) /* Never close stdout */
  1170.          (void) fclose(outfile);
  1171.       outfile = stdout; /* Don't dup... */
  1172.       GTterm_init = FALSE;
  1173.    }
  1174.    else {
  1175.       if (outfile != stdout) /* Never close stdout */
  1176.          (void) fclose(outfile);
  1177.       outfile = fp;
  1178.       GTterm_init = FALSE;
  1179.       UP_redirect (1);
  1180.    }
  1181. }
  1182.  
  1183. /* gt_change_term: get terminal number from name and set terminal type */
  1184. /* returns -1 if unknown, -2 if ambiguous, >=0 is terminal number */
  1185. int
  1186. gt_change_term(name, length)
  1187.     char *name;
  1188.     int length;
  1189. {
  1190.     int i, t = -1;
  1191.  
  1192.     for (i = 0; i < TERMCOUNT; i++) {
  1193.        if (!strncmp(name,term_tbl[i].name,length)) {
  1194.           if (t != -1)
  1195.             return(-2);    /* ambiguous */
  1196.           t = i;
  1197.        }
  1198.     }
  1199.  
  1200.     if (t == -1)            /* unknown */
  1201.      return(t);
  1202.  
  1203.     /* Success: set terminal type now */
  1204.  
  1205.     term = t;
  1206.     term_init = FALSE;
  1207.     name = term_tbl[term].name;
  1208.  
  1209.     /* Special handling for unixplot term type */
  1210.     if (!strncmp("unixplot",name,8)) {
  1211.        UP_redirect (2);  /* Redirect actual stdout for unixplots */
  1212.     } else if (unixplot) {
  1213.        UP_redirect (3);  /* Put stdout back together again. */
  1214.     }
  1215.  
  1216.     if (interactive)
  1217.      fprintf(stderr, "Terminal type set to '%s'\n", name);
  1218.  
  1219.     return(t);
  1220. }
  1221.  
  1222. /*
  1223.    Routine to detect what terminal is being used (or do anything else
  1224.    that would be nice).  One anticipated (or allowed for) side effect
  1225.    is that the global ``term'' may be set. 
  1226.    The environment variable GNUTERM is checked first; if that does
  1227.    not exist, then the terminal hardware is checked, if possible, 
  1228.    and finally, we can check $TERM for some kinds of terminals.
  1229. */
  1230. /* thanks to osupyr!alden (Dave Alden) for the original GNUTERM code */
  1231. gt_init_terminal()
  1232. {
  1233.     char *term_name = NULL;
  1234.     int t;
  1235.     char *term = NULL;        /* from TERM environment var */
  1236. #ifdef X11
  1237.     char *display = NULL;
  1238. #endif
  1239.     char *gnuterm = NULL;
  1240.  
  1241.     /* GNUTERM environment variable is primary */
  1242.     gnuterm = getenv("GNUTERM");
  1243.     if (gnuterm != (char *)NULL)
  1244.      term_name = gnuterm;
  1245.     else {
  1246. #ifdef __TURBOC__
  1247.        term_name = turboc_init();
  1248.        term = (char *)NULL; /* shut up turbo C */
  1249. #endif
  1250.        
  1251. #ifdef vms
  1252.        term_name = vms_init();
  1253. #endif
  1254.        
  1255. #ifdef SUN
  1256.        term = getenv("TERM");    /* try $TERM */
  1257.        if (term_name == (char *)NULL
  1258.           && term != (char *)NULL && strcmp(term, "sun") == 0)
  1259.         term_name = "sun";
  1260. #endif /* sun */
  1261.  
  1262. #ifdef GPR
  1263.    if (gpr_isa_pad()) term_name = "gpr";       /* find out whether stdout is a DM pad. See term/gpr.trm */
  1264. #else
  1265. #ifdef APOLLO
  1266.    if (apollo_isa_pad()) term_name = "apollo"; /* find out whether stdout is a DM pad. See term/apollo.trm */
  1267. #endif /* APOLLO */
  1268. #endif /* GPR    */
  1269.  
  1270. #ifdef X11
  1271.        term = getenv("TERM");    /* try $TERM */
  1272.        if (term_name == (char *)NULL
  1273.           && term != (char *)NULL && strcmp(term, "xterm") == 0)
  1274.         term_name = "x11";
  1275.        display = getenv("DISPLAY");
  1276.        if (term_name == (char *)NULL && display != (char *)NULL)
  1277.         term_name = "x11";
  1278. #endif /* x11 */
  1279.  
  1280. #ifdef AMIGASCREEN
  1281.        term_name = "amiga";
  1282. #endif
  1283.  
  1284. #ifdef UNIXPC
  1285.            if (iswind() == 0) {
  1286.               term_name = "unixpc";
  1287.            }
  1288. #endif /* unixpc */
  1289.  
  1290. #ifdef CGI
  1291.        if (getenv("CGIDISP") || getenv("CGIPRNT"))
  1292.          term_name = "cgi";
  1293. #endif /*CGI */
  1294.     }
  1295.  
  1296.     /* We have a name, try to set term type */
  1297.     if (term_name != NULL && *term_name != '\0') {
  1298.        t = gt_change_term(term_name, strlen(term_name));
  1299.        if (t == -1)
  1300.         fprintf(stderr, "Unknown terminal name '%s'\n", term_name);
  1301.        else if (t == -2)
  1302.         fprintf(stderr, "Ambiguous terminal name '%s'\n", term_name);
  1303.        else                /* successful */
  1304.         ;
  1305.     }
  1306. }
  1307.  
  1308.  
  1309. #ifdef __TURBOC__
  1310. static char *
  1311. turboc_init()
  1312. {
  1313.   int g_driver,g_mode;
  1314.   char far *c1,*c2;
  1315.   char *term_name = NULL;
  1316.   struct text_info tinfo;       /* So we can restore starting text mode. */
  1317.  
  1318. /* Some of this code including BGI drivers is copyright Borland Intl. */
  1319.     g_driver=DETECT;
  1320.           get_path();
  1321.     gettextinfo(&tinfo);
  1322.         initgraph(&g_driver,&g_mode,path);
  1323.         c1=getdrivername();
  1324.         c2=getmodename(g_mode);
  1325.           switch (g_driver){
  1326.             case -2: fprintf(stderr,"Graphics card not detected.\n");
  1327.                      break;
  1328.             case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
  1329.                      break;
  1330.             case -4: fprintf(stderr,"Invalid BGI driver file.\n");
  1331.                      break;
  1332.             case -5: fprintf(stderr,"Insufficient memory to load ",
  1333.                              "graphics driver.");
  1334.                      break;
  1335.             case 1 : term_name = "cga";
  1336.                      break;
  1337.             case 2 : term_name = "mcga";
  1338.                      break;
  1339.             case 3 : 
  1340.             case 4 : term_name = "egalib";
  1341.                      break;
  1342.             case 7 : term_name = "hercules";
  1343.                      break;
  1344.             case 8 : term_name = "att";
  1345.                      break;
  1346.             case 9 : term_name = "vgalib";
  1347.                      break;
  1348.             }
  1349.         closegraph();
  1350.         textmode(tinfo.currmode);
  1351.     clrscr();
  1352.     fprintf(stderr,"\tTC Graphics, driver %s  mode %s\n",c1,c2);
  1353.   return(term_name);
  1354. }
  1355. #endif /* __TURBOC__ */
  1356.  
  1357. /*
  1358.     This is always defined so we don't have to have command.c know if it
  1359.     is there or not.
  1360. */
  1361. #ifndef UNIXPLOT
  1362. UP_redirect(caller) int caller; 
  1363. {
  1364.     caller = caller;    /* to stop Turbo C complaining 
  1365.                          * about caller not being used */
  1366. }
  1367. #else
  1368. UP_redirect (caller)
  1369. int caller;
  1370. /*
  1371.     Unixplot can't really write to outfile--it wants to write to stdout.
  1372.     This is normally ok, but the original design of gnuplot gives us
  1373.     little choice.  Originally users of unixplot had to anticipate
  1374.     their needs and redirect all I/O to a file...  Not very gnuplot-like.
  1375.  
  1376.     caller:  1 - called from SET OUTPUT "FOO.OUT"
  1377.              2 - called from SET TERM UNIXPLOT
  1378.              3 - called from SET TERM other
  1379.              4 - called from SET OUTPUT
  1380. */
  1381. {
  1382.     switch (caller) {
  1383.     case 1:
  1384.     /* Don't save, just replace stdout w/outfile (save was already done). */
  1385.         if (unixplot)
  1386.             *(stdout) = *(outfile);  /* Copy FILE structure */
  1387.     break;
  1388.     case 2:
  1389.         if (!unixplot) {
  1390.             fflush(stdout);
  1391.             save_stdout = *(stdout);
  1392.             *(stdout) = *(outfile);  /* Copy FILE structure */
  1393.             unixplot = 1;
  1394.         }
  1395.     break;
  1396.     case 3:
  1397.     /* New terminal in use--put stdout back to original. */
  1398.         closepl();
  1399.         fflush(stdout);
  1400.         *(stdout) = save_stdout;  /* Copy FILE structure */
  1401.         unixplot = 0;
  1402.     break;
  1403.     case 4:
  1404.     /*  User really wants to go to normal output... */
  1405.         if (unixplot) {
  1406.             fflush(stdout);
  1407.             *(stdout) = save_stdout;  /* Copy FILE structure */
  1408.         }
  1409.     break;
  1410.     }
  1411. }
  1412. #endif
  1413.  
  1414.  
  1415. /* test terminal by drawing border and text */
  1416. /* called from command test */
  1417. gt_test_term()
  1418. {
  1419.     register struct termentry *t = &term_tbl[term];
  1420.     char *str;
  1421.     int x,y, xl,yl, i;
  1422.     unsigned int xmax, ymax;
  1423.     char label[MAX_ID_LEN];
  1424.     int scaling;
  1425.  
  1426.     if (!term_init) {
  1427.        (*t->init)();
  1428.        term_init = TRUE;
  1429.     }
  1430.     screen_ok = FALSE;
  1431.     scaling = (*t->scale)(xsize, ysize);
  1432.     xmax = (unsigned int)(t->xmax * (scaling ? 1 : xsize));
  1433.     ymax = (unsigned int)(t->ymax * (scaling ? 1 : ysize));
  1434.     (*t->graphics)();
  1435.     /* border linetype */
  1436.     (*t->linetype)(-2);
  1437.     (*t->move)(0,0);
  1438.     (*t->vector)(xmax-1,0);
  1439.     (*t->vector)(xmax-1,ymax-1);
  1440.     (*t->vector)(0,ymax-1);
  1441.     (*t->vector)(0,0);
  1442.     (void) (*t->justify_text)(LEFT);
  1443.     (*t->put_text)(t->h_char*5,ymax-t->v_char*3,"Terminal Test");
  1444.     /* axis linetype */
  1445.     (*t->linetype)(-1);
  1446.     (*t->move)(xmax/2,0);
  1447.     (*t->vector)(xmax/2,ymax-1);
  1448.     (*t->move)(0,ymax/2);
  1449.     (*t->vector)(xmax-1,ymax/2);
  1450.     /* test width and height of characters */
  1451.     (*t->linetype)(-2);
  1452.     (*t->move)(  xmax/2-t->h_char*10,ymax/2+t->v_char/2);
  1453.     (*t->vector)(xmax/2+t->h_char*10,ymax/2+t->v_char/2);
  1454.     (*t->vector)(xmax/2+t->h_char*10,ymax/2-t->v_char/2);
  1455.     (*t->vector)(xmax/2-t->h_char*10,ymax/2-t->v_char/2);
  1456.     (*t->vector)(xmax/2-t->h_char*10,ymax/2+t->v_char/2);
  1457.     (*t->put_text)(xmax/2-t->h_char*10,ymax/2,
  1458.         "12345678901234567890");
  1459.     /* test justification */
  1460.     (void) (*t->justify_text)(LEFT);
  1461.     (*t->put_text)(xmax/2,ymax/2+t->v_char*6,"left justified");
  1462.     str = "centre+d text";
  1463.     if ((*t->justify_text)(CENTRE))
  1464.         (*t->put_text)(xmax/2,
  1465.                 ymax/2+t->v_char*5,str);
  1466.     else
  1467.         (*t->put_text)(xmax/2-strlen(str)*t->h_char/2,
  1468.                 ymax/2+t->v_char*5,str);
  1469.     str = "right justified";
  1470.     if ((*t->justify_text)(RIGHT))
  1471.         (*t->put_text)(xmax/2,
  1472.                 ymax/2+t->v_char*4,str);
  1473.     else
  1474.         (*t->put_text)(xmax/2-strlen(str)*t->h_char,
  1475.                 ymax/2+t->v_char*4,str);
  1476.     /* test text angle */
  1477.     str = "rotated ce+ntred text";
  1478.     if ((*t->text_angle)(1)) {
  1479.         if ((*t->justify_text)(CENTRE))
  1480.             (*t->put_text)(t->v_char,
  1481.                 ymax/2,str);
  1482.         else
  1483.             (*t->put_text)(t->v_char,
  1484.                 ymax/2-strlen(str)*t->h_char/2,str);
  1485.     }
  1486.     else {
  1487.         (void) (*t->justify_text)(LEFT);
  1488.         (*t->put_text)(t->h_char*2,ymax/2-t->v_char*2,"Can't rotate text");
  1489.     }
  1490.     (void) (*t->justify_text)(LEFT);
  1491.     (void) (*t->text_angle)(0);
  1492.     /* test tic size */
  1493.     (*t->move)(xmax/2+t->h_tic*2,0);
  1494.     (*t->vector)(xmax/2+t->h_tic*2,t->v_tic);
  1495.     (*t->move)(xmax/2,t->v_tic*2);
  1496.     (*t->vector)(xmax/2+t->h_tic,t->v_tic*2);
  1497.     (*t->put_text)(xmax/2+t->h_tic*2,t->v_tic*2+t->v_char/2,"test tics");
  1498.     /* test line and point types */
  1499.     x = xmax - t->h_char*4 - t->h_tic*4;
  1500.     y = ymax - t->v_char;
  1501.     for ( i = -2; y > t->v_char; i++ ) {
  1502.         (*t->linetype)(i);
  1503.         (void) sprintf(label,"%d",i);
  1504.         if ((*t->justify_text)(RIGHT))
  1505.             (*t->put_text)(x,y,label);
  1506.         else
  1507.             (*t->put_text)(x-strlen(label)*t->h_char,y,label);
  1508.         (*t->move)(x+t->h_char,y);
  1509.         (*t->vector)(x+t->h_char*4,y);
  1510.         if ( i >= -1 )
  1511.             (*t->point)(x+t->h_char*4+t->h_tic*2,y,i);
  1512.         y -= t->v_char;
  1513.     }
  1514.     /* test some arrows */
  1515.     (*t->linetype)(0);
  1516.     x = xmax/4;
  1517.     y = ymax/4;
  1518.     xl = t->h_tic*5;
  1519.     yl = t->v_tic*5;
  1520.     (*t->arrow)(x,y,x+xl,y,TRUE);
  1521.     (*t->arrow)(x,y,x+xl/2,y+yl,TRUE);
  1522.     (*t->arrow)(x,y,x,y+yl,TRUE);
  1523.     (*t->arrow)(x,y,x-xl/2,y+yl,FALSE);
  1524.     (*t->arrow)(x,y,x-xl,y,TRUE);
  1525.     (*t->arrow)(x,y,x-xl,y-yl,TRUE);
  1526.     (*t->arrow)(x,y,x,y-yl,TRUE);
  1527.     (*t->arrow)(x,y,x+xl,y-yl,TRUE);
  1528.     /* and back into text mode */
  1529.     (*t->text)();
  1530. }
  1531.  
  1532.  
  1533. #ifdef PC
  1534. /* output for some terminal types must be binary to stop non Unix computers
  1535.    changing \n to \r\n. 
  1536.    If the output is not STDOUT, the following code reopens outfile 
  1537.    with binary mode. */
  1538. void
  1539. reopen_binary()
  1540. {
  1541. char filename[MAX_ID_LEN+1];
  1542.  
  1543.     if (strcmp(outstr,"STDOUT")) {
  1544.         (void) fclose(outfile);
  1545.         (void) strcpy(filename,outstr+1);    /* remove quotes */
  1546.         filename[strlen(filename)-1] = '\0';
  1547.         if ( (outfile = fopen(filename,"wb")) == (FILE *)NULL ) {
  1548.             if ( (outfile = fopen(filename,"w")) == (FILE *)NULL ) {
  1549.                 os_error("cannot reopen file with binary type; output unknown",
  1550.                     NO_CARET);
  1551.             } 
  1552.             else {
  1553.     os_error("cannot reopen file with binary type; output reset to ascii", 
  1554.                     NO_CARET);
  1555.             }
  1556.         }
  1557.     }
  1558. }
  1559. #endif
  1560.  
  1561. #ifdef vms
  1562. /* these are needed to modify terminal characteristics */
  1563. #include <descrip.h>
  1564. #include <iodef.h>
  1565. #include <ttdef.h>
  1566. #include <tt2def.h>
  1567. #include <dcdef.h>
  1568. #include <ssdef.h>
  1569. #include <stat.h>
  1570. #include <fab.h>
  1571. static unsigned short   chan;
  1572. static int  old_char_buf[3], cur_char_buf[3];
  1573. $DESCRIPTOR(sysoutput_desc,"SYS$OUTPUT");
  1574.  
  1575. static char *vms_init()
  1576. /*
  1577.  * Determine if we have a regis terminal
  1578.  * and save terminal characteristics
  1579. */
  1580. {
  1581.    /* Save terminal characteristics in old_char_buf and
  1582.    initialise cur_char_buf to current settings. */
  1583.    int i;
  1584.    sys$assign(&sysoutput_desc,&chan,0,0);
  1585.    sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,old_char_buf,12,0,0,0,0);
  1586.    for (i = 0 ; i < 3 ; ++i) cur_char_buf[i] = old_char_buf[i];
  1587.    sys$dassgn(chan);
  1588.  
  1589.    /* Test if terminal is regis */
  1590.    if ((cur_char_buf[2] & TT2$M_REGIS) == TT2$M_REGIS) return("regis");
  1591.    return(NULL);
  1592. }
  1593.  
  1594. static void
  1595. vms_reset()
  1596. /* set terminal to original state */
  1597. {
  1598.    int i;
  1599.    sys$assign(&sysoutput_desc,&chan,0,0);
  1600.    sys$qiow(0,chan,IO$_SETMODE,0,0,0,old_char_buf,12,0,0,0,0);
  1601.    for (i = 0 ; i < 3 ; ++i) cur_char_buf[i] = old_char_buf[i];
  1602.    sys$dassgn(chan);
  1603. }
  1604.  
  1605. static void
  1606. term_mode_tek()
  1607. /* set terminal mode to tektronix */
  1608. {
  1609.    long status;
  1610.    if (outfile != stdout) return; /* don't modify if not stdout */
  1611.    sys$assign(&sysoutput_desc,&chan,0,0);
  1612.    cur_char_buf[0] = 0x004A0000 | DC$_TERM | (TT$_TEK401X<<8);
  1613.    cur_char_buf[1] = (cur_char_buf[1] & 0x00FFFFFF) | 0x18000000;
  1614.  
  1615.    cur_char_buf[1] &= ~TT$M_CRFILL;
  1616.    cur_char_buf[1] &= ~TT$M_ESCAPE;
  1617.    cur_char_buf[1] &= ~TT$M_HALFDUP;
  1618.    cur_char_buf[1] &= ~TT$M_LFFILL;
  1619.    cur_char_buf[1] &= ~TT$M_MECHFORM;
  1620.    cur_char_buf[1] &= ~TT$M_NOBRDCST;
  1621.    cur_char_buf[1] &= ~TT$M_NOECHO;
  1622.    cur_char_buf[1] &= ~TT$M_READSYNC;
  1623.    cur_char_buf[1] &= ~TT$M_REMOTE;
  1624.    cur_char_buf[1] |= TT$M_LOWER;
  1625.    cur_char_buf[1] |= TT$M_TTSYNC;
  1626.    cur_char_buf[1] |= TT$M_WRAP;
  1627.    cur_char_buf[1] &= ~TT$M_EIGHTBIT;
  1628.    cur_char_buf[1] &= ~TT$M_MECHTAB;
  1629.    cur_char_buf[1] &= ~TT$M_SCOPE;
  1630.    cur_char_buf[1] |= TT$M_HOSTSYNC;
  1631.  
  1632.    cur_char_buf[2] &= ~TT2$M_APP_KEYPAD;
  1633.    cur_char_buf[2] &= ~TT2$M_BLOCK;
  1634.    cur_char_buf[2] &= ~TT2$M_DECCRT3;
  1635.    cur_char_buf[2] &= ~TT2$M_LOCALECHO;
  1636.    cur_char_buf[2] &= ~TT2$M_PASTHRU;
  1637.    cur_char_buf[2] &= ~TT2$M_REGIS;
  1638.    cur_char_buf[2] &= ~TT2$M_SIXEL;
  1639.    cur_char_buf[2] |= TT2$M_BRDCSTMBX;
  1640.    cur_char_buf[2] |= TT2$M_EDITING;
  1641.    cur_char_buf[2] |= TT2$M_INSERT;
  1642.    cur_char_buf[2] |= TT2$M_PRINTER;
  1643.    cur_char_buf[2] &= ~TT2$M_ANSICRT;
  1644.    cur_char_buf[2] &= ~TT2$M_AVO;
  1645.    cur_char_buf[2] &= ~TT2$M_DECCRT;
  1646.    cur_char_buf[2] &= ~TT2$M_DECCRT2;
  1647.    cur_char_buf[2] &= ~TT2$M_DRCS;
  1648.    cur_char_buf[2] &= ~TT2$M_EDIT;
  1649.    cur_char_buf[2] |= TT2$M_FALLBACK;
  1650.  
  1651.    status = sys$qiow(0,chan,IO$_SETMODE,0,0,0,cur_char_buf,12,0,0,0,0);
  1652.    if (status == SS$_BADPARAM) {
  1653.       /* terminal fallback utility not installed on system */
  1654.       cur_char_buf[2] &= ~TT2$M_FALLBACK;
  1655.       sys$qiow(0,chan,IO$_SETMODE,0,0,0,cur_char_buf,12,0,0,0,0);
  1656.    }
  1657.    else {
  1658.       if (status != SS$_NORMAL)
  1659.          lib$signal(status,0,0);
  1660.    }
  1661.    sys$dassgn(chan);
  1662. }
  1663.  
  1664. static void
  1665. term_mode_native()
  1666. /* set terminal mode back to native */
  1667. {
  1668.    int i;
  1669.    if (outfile != stdout) return; /* don't modify if not stdout */
  1670.    sys$assign(&sysoutput_desc,&chan,0,0);
  1671.    sys$qiow(0,chan,IO$_SETMODE,0,0,0,old_char_buf,12,0,0,0,0);
  1672.    for (i = 0 ; i < 3 ; ++i) cur_char_buf[i] = old_char_buf[i];
  1673.    sys$dassgn(chan);
  1674. }
  1675.  
  1676. static void
  1677. term_pasthru()
  1678. /* set terminal mode pasthru */
  1679. {
  1680.    if (outfile != stdout) return; /* don't modify if not stdout */
  1681.    sys$assign(&sysoutput_desc,&chan,0,0);
  1682.    cur_char_buf[2] |= TT2$M_PASTHRU;
  1683.    sys$qiow(0,chan,IO$_SETMODE,0,0,0,cur_char_buf,12,0,0,0,0);
  1684.    sys$dassgn(chan);
  1685. }
  1686.  
  1687. static void
  1688. term_nopasthru()
  1689. /* set terminal mode nopasthru */
  1690. {
  1691.    if (outfile != stdout) return; /* don't modify if not stdout */
  1692.    sys$assign(&sysoutput_desc,&chan,0,0);
  1693.    cur_char_buf[2] &= ~TT2$M_PASTHRU;
  1694.    sys$qiow(0,chan,IO$_SETMODE,0,0,0,cur_char_buf,12,0,0,0,0);
  1695.    sys$dassgn(chan);
  1696. }
  1697.  
  1698. static void
  1699. reopen_binary()
  1700. /* close the file outfile outfile and reopen it with binary type
  1701.    if not already done or outfile == stdout */
  1702. {
  1703.    stat_t stat_buf;
  1704.    char filename[MAX_ID_LEN+1];
  1705.    if (outfile != stdout) { /* don't modify if not stdout */
  1706.       if (!fstat(fileno(outfile),&stat_buf)) {
  1707.          if (stat_buf.st_fab_rfm != FAB$C_FIX) {
  1708.             /* modify only if not already done */
  1709.             (void) fclose(outfile);
  1710.             (void) strcpy(filename,outstr+1);   /* remove quotes */
  1711.             filename[strlen(filename)-1] = '\0';
  1712.             (void) delete(filename);
  1713.             if ((outfile = fopen(filename,"wb","rfm=fix","bls=512","mrs=512"))
  1714.                 == (FILE *)NULL ) {
  1715.                if ( (outfile = fopen(filename,"w")) == (FILE *)NULL ) {
  1716.                  os_error("cannot reopen file with binary type; output unknown",
  1717.                            NO_CARET);
  1718.                }
  1719.                else {
  1720.           os_error("cannot reopen file with binary type; output reset to ascii",
  1721.                            NO_CARET);
  1722.                }
  1723.             }
  1724.          }
  1725.       }
  1726.       else{
  1727.          os_error("cannot reopen file with binary type; output remains ascii",
  1728.                   NO_CARET);
  1729.       }
  1730.    }
  1731. }
  1732.  
  1733. static void
  1734. fflush_binary()
  1735. {
  1736.    typedef short int INT16;     /* signed 16-bit integers */
  1737.    register INT16 k;            /* loop index */
  1738.    if (outfile != stdout) {
  1739.        /* Stupid VMS fflush() raises error and loses last data block
  1740.           unless it is full for a fixed-length record binary file.
  1741.           Pad it here with NULL characters. */
  1742.        for (k = (INT16)((*outfile)->_cnt); k > 0; --k)
  1743.           putc('\0',outfile);
  1744.        fflush(outfile);
  1745.    }
  1746. }
  1747. #endif
  1748.